package com.hrsaas.ext.spider.core;

import java.time.Duration;
import java.time.ZonedDateTime;
import java.util.TimerTask;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;

import com.hrsaas.ext.spider.core.url.URL;

import io.netty.handler.codec.http.HttpRequest;

/**
 * <p>
 * 功能：请求主体
 * <p>
 * 
 * @author wangxiaoliang@kanzhun.com
 *
 *         2018年8月2日
 */
final class RequestInfo {

	final URL url;
	final HttpRequest req;
	final AtomicBoolean cancelled;
	final ResponseFuture handle;
	final ResponseHandler<?> r;
	final AtomicInteger redirectCount = new AtomicInteger();
	final Duration timeout;
	final ZonedDateTime startTime;
	volatile boolean listenerAdded;
	TimerTask timer;
	final boolean dontAggregate;
	final ChunkedContent chunkedBody;

	RequestInfo(URL url, HttpRequest req, AtomicBoolean cancelled, ResponseFuture handle, ResponseHandler<?> r,
			Duration timeout, ZonedDateTime startTime, TimerTask timer, boolean noAggregate,
			ChunkedContent chunkedBody) {
		this.url = url;
		this.req = req;
		this.cancelled = cancelled;
		this.handle = handle;
		this.r = r;
		this.timeout = timeout;
		this.startTime = startTime;
		this.timer = timer;
		this.dontAggregate = noAggregate;
		this.chunkedBody = chunkedBody;
	}

	RequestInfo(URL url, HttpRequest req, AtomicBoolean cancelled, ResponseFuture handle, ResponseHandler<?> r,
			Duration timeout, TimerTask timer, boolean noAggregate, ChunkedContent chunkedBody) {
		this(url, req, cancelled, handle, r, timeout, ZonedDateTime.now(), timer, noAggregate, chunkedBody);
	}

	Duration age() {
		return Duration.between(startTime, ZonedDateTime.now());
	}

	Duration remaining() {
		return timeout == null ? null : timeout.minus(age());
	}

	boolean isExpired() {
		if (timeout != null) {
			return ZonedDateTime.now().isAfter(startTime.plus(timeout));
		}
		return false;
	}

	void cancelTimer() {
		if (timer != null) {
			timer.cancel();
		}
	}

	@Override
	public String toString() {
		return "RequestInfo{" + "url=" + url + ", req=" + req + ", cancelled=" + cancelled + ", handle="
				+ handle + ", r=" + r + ", timeout=" + timeout + '}';
	}
}
